package org.game.db.proxy.bean;

import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import org.base.BaseGoods;
import org.bean.AccountInfo;
import org.bean.PlayerInfo;
import org.cache.GoodsCfgCache;
import org.cfg.DiscreteDataCfg;
import org.cfg.cache.DiscreteDataCfgCache;
import org.constant.BagType;
import org.constant.DiscreteDataID;
import org.constant.smallkey.PlayerDataSmallKey;
import org.game.actor.PlayerActor;
import org.game.constant.GameConstant;
import org.game.constant.SecondsJobStatus;
import org.game.db.bean.Formation;
import org.game.db.bean.Hero;
import org.game.db.bean.Item;
import org.game.db.bean.Player;
import org.game.db.bean.PlayerData;
import org.game.db.bean.Role;
import org.game.db.vo.BackpackVO;
import org.game.db.vo.EquipmentVO;
import org.game.db.vo.PlayerDataVO.DiscreteVO;
import org.game.manager.PlayerManager;
import org.game.util.ProtoUnit;

import com.google.common.collect.Maps;
import com.google.protobuf.GeneratedMessage;
import com.sojoys.artifact.build.data.base.BasePojoProxy;
import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.factory.session.ISession;
import com.sojoys.artifact.manager.MessageManager;
import com.sojoys.artifact.manager.PropManager;
import com.sojoys.artifact.plugin.actor.ActorPlugin;
import com.sojoys.artifact.tools.ToolMap;

import akka.actor.ActorRef;
import akka.actor.Props;

/**
 * @author : DengYing
 * @CreateDate : 2017年11月30日 下午1:19:08
 * @Description ：玩家扩展
 */
public class PlayerProxy extends BasePojoProxy<PlayerProxy, Player> {
	private ActorRef actorRef;
	
	private ISession session;
	/** 聊天室ID */
	private int chatRoomId;
	private boolean online = false;
	/** 账号信息 */
	private AccountInfo accountInfo;
	/** 背包 */
	private Map<Integer, BackpackVO> backpacks = Maps.newHashMap();
	private Map<Long, Hero> herosByDbId = Maps.newHashMap();
	private Map<Integer, Hero> herosByCid = Maps.newHashMap();
	private Map<Long, Role> roles = Maps.newHashMap();
	private boolean isFirstLogin = false;
	
	
	// 助战英雄
	private Hero helpHero = null;
	/**
	 * 当前看板娘
	 */
	private Role currentRole;

	/**
	 * 当前战斗ID
	 */
	private String currentFightId;

	/** 当前阵型 */
	private Formation currentFormation;
	
	/** 助战路人筛选缓存 */
	private Map<Integer,org.bean.PlayerInfo> helpFightPlayers = Maps.newHashMapWithExpectedSize(10);
	
	/** 最后获取好友推荐时间 */
	private long lastORFT;
	
	/** 下一次每秒任务调用时间 */
	private volatile long nextSecondsJobTime = Long.MAX_VALUE;
	/** 
	 * 当前Player的每秒定时器状态 
	 * 0 初始状态 </br>
	 * 1 激活状态 </br>
	 * 2 执行状态 </br>
	 * 3 暂停状态 </br>
	 * 4 强制状态 </br>
	 */
	private volatile SecondsJobStatus secondsJobStatus = SecondsJobStatus.INIT;
	
	public boolean isOnline() {
		return online;
	}

	public void setOnline(boolean online) {
		this.online = online;
	}

	public ISession getSession() {
		return session;
	}

	public void setSession(ISession session) {
		this.session = session;
	}

	public void sendMsg(short commandId,GeneratedMessage msg ){
		if (session!=null) {
			session.sendMessage(MessageManager.me().create(commandId, ProtoUnit.toByte(msg)));
		}
	}

	public void sendMsg(IMessage msg){
		if (session!=null) {
			session.sendMessage(msg);
		}
	}

	/** 当前看板娘 */
	public Role getCurrentRole() {
		return currentRole;
	}

	/** 当前看板娘 */
	public void setCurrentRole(Role currentRole) {
		this.currentRole = currentRole;
	}

	

	public String getCurrentFightId() {
		return currentFightId;
	}

	public void setCurrentFightId(String currentFightId) {
		this.currentFightId = currentFightId;
	}

	public Map<Long, Hero> getHerosByDbId() {
		return herosByDbId;
	}


	public Map<Integer, Hero> getHerosByCid() {
		return herosByCid;
	}


	public Map<Long, Role> getRoles() {
		return roles;
	}

	public void setRoles(Map<Long, Role> roles) {
		this.roles = roles;
	}
	
	public Formation getCurrentFormation() {
		return currentFormation;
	}

	public void setCurrentFormation(Formation currentFormation) {
		this.currentFormation = currentFormation;
	}

	/**
	 * 取得所有背包
	 * @return
	 */
	public Collection<BackpackVO> getBackpacks() {
		return backpacks.values();
	}

	/**
	 * 根据类型取得背包
	 * @param backpackType
	 * @return
	 */
	public BackpackVO getBackpackByType(int backpackType) {
		BackpackVO backpackVO = backpacks.get(backpackType);
		if (backpackVO==null) {
			DiscreteDataCfg cfg = DiscreteDataCfgCache.me().getById(DiscreteDataID.ROLE_BAG);
			int capacity = ToolMap.getInt(backpackType,cfg.getData(),0);
			// 不存在的背包始终有空间
			if (capacity==0) {
				capacity = Integer.MAX_VALUE;
			}
			backpackVO = new BackpackVO(capacity);
			backpacks.put(backpackType, backpackVO);
		}
		return backpackVO;
	}
	
	/**
	 * 根据道具CID取得背包
	 */
	public BackpackVO getBackpackByGoodsCid(int goodsCid){
		BaseGoods baseGoods = GoodsCfgCache.me().get(goodsCid);
		BackpackVO backpackVO = getBackpackByType(baseGoods.getBagType());
		return backpackVO;
	}

	/**
	 * 根据cid获取道具数量
	 */
	public int getGoodsNumByCid(int goodsCid){
		BackpackVO backpackVO = getBackpackByGoodsCid(goodsCid);
		return backpackVO.countByCfg(goodsCid);
	}
	
	/**
	 * 取得代币数量
	 */
	public int getTokenNum(int tokenType){
		BackpackVO backpackVO = getBackpackByType(BagType.NO_BACKPACKS);
		Item gold = backpackVO.getItem(tokenType);
		return gold == null ? 0 : backpackVO.countByCfg(gold.getItemProxy().getCfg());
	}

	public Hero getHelpHero() {
		return helpHero;
	}

	public void setHelpHero(Hero helpHero) {
		this.helpHero = helpHero;
		
		PlayerDataProxy dataProxy = PlayerManager.me().getDataProxy(t);
		DiscreteVO discreteVO = dataProxy.getDiscreteVO();
		discreteVO.setHelpFigntHeroCid(helpHero.getCid());
		discreteVO.setHelpFigntHeroPower(helpHero.getHeroProxy().getFightPower());
		dataProxy.save();
	}
	
	public PlayerInfo toPlayerInfo(){
		PlayerData playerData = t.getPlayerDatasFkPlayerId();
		DiscreteVO discreteVO = playerData.getPlayerDataProxy().getDiscreteVO();
		int helpFightHeroCid = discreteVO.getHelpFigntHeroCid();
		int helpFightHeroFightPower =discreteVO.getHelpFigntHeroPower();
		PlayerInfo info = new PlayerInfo();
		info.setPid(t.getId());
		info.setLvl(t.getLevel());
		info.setFightPower(helpFightHeroFightPower);
		info.setOnline(online);
		info.setName(t.getName());
		info.setUid(t.getUid());
		info.setLanguage(t.getLanguage());
		info.setVip(t.getVipLevel());
		info.setHelpHeroCid(helpFightHeroCid);
		info.setLastLoginDate(t.getLastLoginTime());
		info.setLastOfflineDate(new Date());
		info.setServerId(PropManager.get(GameConstant.GAME_SERVER_ID));
		return info;
	}

	public Map<Integer, org.bean.PlayerInfo> getHelpFightPlayers() {
		return helpFightPlayers;
	}

	public long getLastORFT() {
		return lastORFT;
	}

	public void setLastORFT(long lastORFT) {
		this.lastORFT = lastORFT;
	}

	public ActorRef getActorRef() {
		if (actorRef == null) {
			actorRef = ActorPlugin.getProxy().actorOf(Props.create(PlayerActor.class,t), "playerActor-"+t.getId());
		}
		return actorRef;
	}

	public long getNextSecondsJobTime() {
		return nextSecondsJobTime;
	}

	
	public void setNextSecondsJobTime(long nextSecondsJobTime) {
		this.nextSecondsJobTime = Math.min(this.nextSecondsJobTime, nextSecondsJobTime);
		// 激活
		setSecondsJobStatus(SecondsJobStatus.ACTIVATE);
	}
	
	/**
	 * 强制执行
	 */
	public void startSecondsJob(){
		// 强制执行
		setSecondsJobStatus(SecondsJobStatus.COMPEL);
	}

	public SecondsJobStatus getSecondsJobStatus() {
		return secondsJobStatus;
	}

	public void setSecondsJobStatus(SecondsJobStatus secondsJobStatus) {
		this.secondsJobStatus = secondsJobStatus;
	}

	
	/**
	 * 根据CID & quality 取得持有英雄数量
	 * @param heroCid
	 * @param quality
	 * @return
	 */
	public int getHeroCountByHeroIdAndQuality(int heroCid,int quality){
		Hero hero = null;
		int count = 0;
		for (Entry<Long, Hero> e : herosByDbId.entrySet()) {
			hero = e.getValue();
			if (heroCid != 0 && heroCid != hero.getCid()) {
				continue;
			}
			
			if (quality != 0 && quality != hero.getHeroProxy().getQuality()) {
				continue;
			}
			count++;
		}
		return count;
	}
	
	/**
	 * 根据CID 取得持有英雄最大等级
	 * @param heroCid
	 * @param quality
	 * @return
	 */
	public int getMaxHeroLvl(int heroCid){
		Hero hero = null;
		int maxLvl = 0;
		for (Entry<Long, Hero> e : herosByDbId.entrySet()) {
			hero = e.getValue();
			if (heroCid != 0 && heroCid != hero.getCid()) {
				continue;
			}
			maxLvl = Math.max(maxLvl, hero.getLvl());
		}
		return maxLvl;
	}
	
	
	/**
	 * 根据CID 取得持有英雄最大突破等级
	 * @param heroCid
	 * @param quality
	 * @return
	 */
	public int getMaxHeroAdvancedLvl(int heroCid){
		Hero hero = null;
		int maxLvl = 0;
		for (Entry<Long, Hero> e : herosByDbId.entrySet()) {
			hero = e.getValue();
			if (heroCid != 0 && heroCid != hero.getCid()) {
				continue;
			}
			maxLvl = Math.max(maxLvl, hero.getAdvancedLvl());
		}
		return maxLvl;
	}
	
	/**
	 * 根据CID 取得持有突破等级达到limit的英雄数量
	 * @param heroCid
	 * @param quality
	 * @return
	 */
	public int getMaxHeroAdvancedLvlCount(int heroCid,int limitLvl){
		Hero hero = null;
		int count = 0;
		for (Entry<Long, Hero> e : herosByDbId.entrySet()) {
			hero = e.getValue();
			if (heroCid != 0 && heroCid != hero.getCid()) {
				continue;
			}
			if (hero.getAdvancedLvl() < limitLvl) {
				continue;
			}
			count++;
		}
		return count;
	}
	
	/**
	 * 取得玩家最大装备等级
	 * @param equipId
	 * @return
	 */
	public int getMaxEquipLvl(int equipId){
		BackpackVO backpackVO = getBackpackByType(BagType.EQUIPMENT);
		Collection<Item> equips = backpackVO.getAll();
		int maxLvl = 0;
		for (Item item : equips) {
			EquipmentVO equip = (EquipmentVO) item;
			if (!(item instanceof EquipmentVO)) {
				continue;
			}
			if (equipId != 0 && equipId != item.getCid()) {
				continue;
			}
			maxLvl = Math.max(maxLvl, equip.getLevel());
		}
		return maxLvl;
	}

	public AccountInfo getAccountInfo() {
		return accountInfo;
	}

	public void setAccountInfo(AccountInfo accountInfo) {
		this.accountInfo = accountInfo;
	}
	
	/**
	 * 是否是管理员
	 * @return
	 */
	public boolean isAdmin(){
		boolean admin = false;
		if (accountInfo != null) {
			admin = accountInfo.isAdmin();
		}
		return admin;
	}

    /**
     * 是否首次登录
     */
    public boolean isFirstLogin() {
		return isFirstLogin;
	}

    /**
     * 设置首次登录
     */
	public PlayerProxy setFirstLogin(boolean firstLogin) {
		isFirstLogin = firstLogin;
		return this;
	}

	public int getChatRoomId() {
		return chatRoomId;
	}

	public void setChatRoomId(int chatRoomId) {
		this.chatRoomId = chatRoomId;
	}
	
	
}
